/* Copyright (c) 2009, Michael Patraw
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * The name of Michael Patraw may not be used to endorse or promote
 *       products derived from this software without specific prior written
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Michael Patraw ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Michael Patraw BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 
 
/**
 * Uses linear hashing.
 */
#ifndef AT_CONTAINER_HASH_MAP_H
#define AT_CONTAINER_HASH_MAP_H

#include <at/util/ints.h>

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************\
\******************************************************************************/

/**
 * The hash table.
 */
typedef struct atHashMap_T *atHashMap_T;
typedef atuint (*atHashMap_F) (const char *str);

/******************************************************************************\
\******************************************************************************/

/**
 * Creates a new hash structure.
 *
 * \param[in] n The initial size of the table. The allocated size will be
 *              twice this amount.
 *
 * \return A new hash table.
 */
atHashMap_T atHashMap_Malloc(atuint n);



/**
 * Frees a hash table. Does not free the user (void *) data.
 *
 * \param[in] h The hash table.
 *
 * \return Nothing.
 */
void atHashMap_Free(atHashMap_T h);



/**
 * Inserts a table entry with the specified data. Replaces if a duplicate is
 * found, possibly losing the data stored there.
 *
 * \param[in] h The hash table.
 * \param[in] key The key to the data.
 * \param[in] data User defined data.
 *
 * \return -1 on failure, 0 on success.
 */
atint atHashMap_Insert(atHashMap_T h, const char *key, void *data);



/**
 * Removes a table entry.
 *
 * \param[in] h The hash table.
 * \param[in] key The key to the data.
 *
 * \return The user data or NULL if there is no entry for the key.
 */
void *atHashMap_Remove(atHashMap_T h, const char *key);



/**
 * Retrieves a table entry.
 *
 * \param[in] h The hash table.
 * \param[in] key The key to the data.
 *
 * \return The user data or NULL if there is no entry for the key.
 */
void *atHashMap_Retrieve(atHashMap_T h, const char *key);



/**
 * Applies a function to every user data on the table.
 *
 * \param[in] h The hash table.
 * \param[in] fun The function; takes the key and data as args and returns void.
 *
 * \return Nothing.
 */
void atHashMap_Apply(atHashMap_T h, void (*fun) (const char *, void *));



/**
 * Sets the hash function. The default hash function is...
 *
 * #define MULT 37
 * static unsigned int hash(const char *str)
 * {
 *     unsigned int key = 0;
 *     for ( ; *str; ++str)
 *         key = MULT * key + *str;
 *     return key;
 * }
 *
 * \param[in] hf The function; takes a string and returns the hash. (unbounded)        
 *
 * \return Nothing.
 */
void atHashMap_SetHashFunc(atHashMap_F hf);

#ifdef __cplusplus
}
#endif

#endif
